/**
 * 此js文件是对axios的封装。
 * 详细信息请查看axios官网，https://github.com/axios/axios
 */
import axios from 'axios'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import config from '@/config/index.js'
import {
    ElMessage as Message
} from 'element-plus'
import {isArray, isObject, isEmpty} from "@/utils/object";
import store from '@/store/index'

/**
 * BASE_URL从配置文件中加载
 */
export const BASE_URL = config.URL

/**
 * 是否启用进度条。如果为true必需导入nprogress
 */
const ENABLE_NPROGRESS = true

/**
 * 请求失败时是否提示错误。如果为true必需导入Message
 */
const ENABLE_REQUEST_ERROR_TIP = true

/**
 * 默认请求配置
 */
const DEFAULT_CONFIG = {
    /**
     * 默认请求方法
     */
    method: 'GET',
    /**
     * BaseURL
     */
    baseURL: BASE_URL,
    /**
     * 请求头
     */
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    /**
     * 参数转成QueryString格式
     */
    paramsSerializer: (data) => {
        if (isObject(data)) {
            let arr = []
            for (let key in data) {
                try{
                    if (isObject(data[key]) || isArray(data[key])) {
                        arr.push(`${key}=${encodeURI(JSON.stringify(data[key]))}`)
                    } else {
                        arr.push(`${key}=${encodeURI(data[key])}`)
                    }
                }catch (e){}

            }
            return arr.join("&")
        } else {
            return JSON.stringify(data)
        }
    },
    /**
     * 超时时间。为0则无限等待
     */
    timeout: 5000,
    /**
     * 响应的数据。
     * 可以是：arraybuffer, json, text, blob
     */
    responseType: 'json',
    /**
     * 是否发送Cookie
     */
    withCredentials: true,
    /**
     * 上传事件
     */
    onUploadProgress: undefined,
    /**
     * 下载事件
     */
    onDownloadProgress: undefined,
    /**
     * 代理
     */
    proxy: undefined
}

/**
 * 请求拦截
 */
axios.interceptors.request.use(function (config) {
    if(store.state.user.user){
        config.headers.Authorization=store.state.user.user.token
    }
    if (ENABLE_NPROGRESS && NProgress) {
        NProgress.start()
    }
    return config
});

/**
 * 响应拦截
 */
axios.interceptors.response.use(function (config) {
    if (ENABLE_NPROGRESS && NProgress) {
        NProgress.done()
    }
    return config
}, function (error) {
    if (ENABLE_REQUEST_ERROR_TIP && Message) {
        Message.error("请求失败")
    }
    if (ENABLE_NPROGRESS && NProgress) {
        NProgress.done()
    }
    return Promise.reject(error);
});

/**
 * get方法
 * @param url 请求地址
 * @param params url中的参数
 * @param options 可覆盖默认的配置
 */
export const $get = function (url, params, options) {
    return new Promise((resolve, reject) => {
        axios.request(Object.assign({}, DEFAULT_CONFIG, {
            url,
            params,
            baseURL: BASE_URL
        }, options)).then(resolve).catch(reject)
    })
}
/**
 * post方法，发送普通post请求。无法上传文件
 * @param url 请求地址
 * @param data 表单数据，会被转成QueryString，所以无法上传文件
 * @param options 可覆盖默认的配置 如果想在开发者工具中预览到图片内容，请在options中设置headers.Accept为image/jpeg
 */
export const $post = function (url, data, options) {
    return new Promise((resolve, reject) => {
        axios.request(Object.assign({}, DEFAULT_CONFIG, {
            data: DEFAULT_CONFIG.paramsSerializer(data),
            url,
            method: 'POST',
        }, options)).then(resolve).catch(reject)
    })
}

/**
 * post方法，用于上传文件操作，也可以做到$post方法的作用
 * @param url 请求地址
 * @param data 表单数据
 * @param options 可覆盖默认的配置。如果想在开发者工具中预览到图片内容，请在options中设置headers.Accept为image/jpeg
 */
export const $POST = function (url, data, options) {
    let fd = new FormData()
    for (let key in data) {
        if (!isEmpty(data[key])) {
            if (isArray(data[key]) && data[key].every(file => file.constructor === File)) {
                data[key].forEach(file => {
                    fd.append(key, file)
                })
            } else {
                fd.append(key, data[key])
            }
        }
    }
    return new Promise((resolve, reject) => {
        axios.request(Object.assign({}, DEFAULT_CONFIG, {
            timeout: 1000 * 60 * 10,
            responseType: 'blob'
        }, {
            data: fd,
            url,
            method: 'POST',
        }, options)).then(resolve).catch(reject)
    })
}